var MyUtils = {
	getJson: function(url, showWaiting, success, failure){
		if (showWaiting){
			this.waitLoading();
		}
		Ext.Ajax.request({
			url: url,
			success: function(response, options){
				if (!_error_ && typeof success === 'function'){
					success(MyUtils.getResponseJson(response));
				}
			},
			failure: function(response, options){
				if (typeof success === 'function'){
					failure(response, options);
				}
			},
			scope: this
		});
		_error_ = false;
	},
	
	request: function(url, showWaiting, success, failure){
		if (showWaiting){
			this.waitSubmitting();
		}
		Ext.Ajax.request({
			url: url,
			success: function(response, options){
				if (!_error_ && typeof success === 'function'){
					success(response, options);
				}
			},
			failure: function(response, options){
				if (typeof failure === 'function'){
					failure(response, options);
				}
			}
		});
		_error_ = false;
	},
	
	get: function(url, showWaiting, success, failure){
		if (showWaiting){
			this.waitSubmitting();
		}
		Ext.Ajax.request({
			url: url,
			success: function(response, options){
				if (!_error_ && typeof success === 'function'){
					success(response.responseText);
				}
			},
			failure: function(response, options){
				if (typeof failure === 'function'){
					failure(response, options);
				}
			}
		});
		_error_ = false;
	},
	
	/**
	 * 对服务端返回结果检查是否有错，如果有错，返回错误信息，没有则返回null。
	 * 如果title参数不为空，则同时提示错误信息。
	 */
	responseError: function(response, title, callback){
		if (!response || !response.responseText)
			return null;
		var errorMsg, errorStack;
		resultText = this.trim(response.responseText);
		//先处理json，如果处理出错再继续处理文本
		try{
			var action = {result: this.getResponseJson(response)};
			return this.actionError(action, title);
		}
		catch(ex){}
		if (resultText.indexOf('<html>') != -1){
			var errorWin = new top.Ext.Window({
	            title: title || '内部错误',
	            width: 600,
	            height: 400,
	            layout: 'fit',
	            plain:true,
	            modal: true,
	            bodyStyle:'padding:5px;',
	            buttonAlign:'center',
	            html: resultText,
	            buttons: [{
	                text: '关闭',
	                handler: function(){errorWin.close();}
	            }]
	        });
	    	errorWin.show();
			return true;
		}
		//没有错误信息返回null
		if (resultText.indexOf("_ERROR_MESSAGE_:") == -1){
			return null;
		}
		//检查是否有异常栈
		var i = resultText.indexOf("_ERROR_STACK_:");
		if (i == -1){
			errorMsg = resultText.substring(16); //去掉_ERROR_MESSAGE_:
		}
		else{
			errorMsg = resultText.substring(16, i);
			errorStack = this.trim(resultText.substring(i + 14));
		}
		
		if (title && errorStack){ //意外错误
			this._showErrorWin(errorMsg, errorStack, title, callback);
		}
		else if (title){ //可知错误
			this.showMsg(title, errorMsg, 'w', callback);
		}
		return errorMsg;
	},
	/**
	 * 专门针对Ext的ajax错误处理
	 * @param action
	 * @param title
	 */
	actionError: function(action, title, callback){
		if (action && action.result){
			if (title && action.result.loginTimeout){
				alert('登陆超时！');
				top.location.href = top.location.href;
			}
			else if (title && action.result.errorStack){
				this._showErrorWin(action.result.errorMsg, action.result.errorStack, title);
			}
			else if (action.result.errorMsg && title){
				this.showMsg(title, action.result.errorMsg, 'w', callback);
			}
			return action.result.errorMsg;
		}
		else if (action && action.response){
			return this.responseError(action.response, title);
		}
	},
	showMsg: function(title, msg, icon, callback){
		var Ext = top.Ext || Ext;
		if (Ext){
			if (icon == 1 || icon == 'i') icon = Ext.MessageBox.INFO;
			else if (icon == 2 || icon == 'w') icon = Ext.MessageBox.WARNING;
			else if (icon == 3 || icon == 'e') icon = Ext.MessageBox.ERROR;
			else icon = Ext.MessageBox.INFO;
			Ext.MessageBox.show({
				title: title,
				msg: msg,
				buttons: Ext.MessageBox.OK,
				fn: callback,
				icon: icon
		    });
		}
		else{
			alert(title + ":\n\n" + msg);
			if (typeof callback === 'function'){
				callback.call();
			}
		}
	},
	
	alert: function(msg){
		this.showMsg('提示', msg, 'w');
	},
	
	/**
	 * 弹出提示窗口，并在一段时间内自动关闭
	 */
	hint: function(msg, timeout){
		var Ext = top.Ext || Ext;
        Ext.MessageBox.show({
            title: '提示',
            msg: msg,
            modal: false,
            icon: top.Ext.MessageBox.WARNING
        });
        setTimeout(function(){Ext.MessageBox.hide();}, timeout || 1000);
	},
	
	wait: function(msg){
		var Ext = top.Ext || Ext;
		this.loadMark = new Ext.LoadMask(Ext.getBody(),{msg:msg});
		this.loadMark.show();
	},
	waitLoading: function(){
		this.wait('加载数据中……');
	},
	waitSubmitting: function(){
		this.wait('提交请求中……');
	},
	stopWaiting: function(){
		if (this.loadMark){
			this.loadMark.hide();
		}
	},
	
	formNotValid: function(form){
		if (!form.isValid()){
			MyUtils.hint('表单验证不通过');
			return true;
		}
		return false;
	},
	
	getResponseJson: function(response){
		return Ext.util.JSON.decode(response.responseText);
	},
	
	trim: function(str){
		return str ? str.replace(/^\s+|\s+$/g, "") : str;
	},
	
	/**
	 * 创建符合extjs表单的setValues方法的参数的数组。
	 * @param obj 要填充到表单的值对象
	 * @param prefix 表单字段名的前缀
	 */
	toFormValues: function(obj, prefix){
		var prefix = prefix || '';
		var values = [];
		for (var p in obj){
			values.push({id: prefix + p, value: obj[p]});
		}
		return values;
	},
	
	getWinWidth: function(width){
		var bodyWidth = top.Ext.getBody().getWidth();
		if (!width || width >= bodyWidth){
			return bodyWidth - 20;
		}
		return width;
	},
	
	getWinHeight: function(height){
		var bodyHeight = top.Ext.getBody().getHeight();
		if (!height || height >= bodyHeight){
			return bodyHeight - 20;
		}
		return height;
	},
	
	each: function(array, fn){
		if (!array || typeof fn != 'function') return;
		if (!array instanceof Array) array = [array];
		for (var i = 0; i < array.length; i ++){
			if (fn(array[i],i) === false) return;
		}
	},
	
	findItemBySpecialAttr: function(array, attrName, attrValue){
		if (!array || !attrName || !attrValue || !array instanceof Array) return null;
		for (var i = 0; i < array.length; i ++){
			if (!array[i]) continue;
			if (array[i][attrName] === attrValue){
				return array[i];
			}
		}
		return null;
	},
	
	_showErrorWin: function(errorMsg, errorStack, title, callback){
		var self = this;
		var Ext = top.Ext || Ext;
		var errorWin = new Ext.Window({
            title: title || '内部错误',
            layout: 'fit',
            plain:true,
            modal: true,
            bodyStyle:'padding:5px;',
            buttonAlign:'center',
            items: [new Ext.FormPanel({
           		baseCls: 'x-plain',
           		labelWidth: 0,
            	items:[{
           			baseCls: 'x-plain',
            		height: 60,
            		bodyStyle: 'margin-bottom:5px',
            		html:'<div class="icon-error" style="height:100%;padding-left:40px;"><div style="font-size:14px;color:red;margin-bottom:3px;">发生内部错误：</div>' + errorMsg + '</div>'
            	},{
			        xtype: 'fieldset',
			        title: '异常信息',
			        autoHeight: true,
			        layout: 'form',
            		collapsed: true,
        			collapsible: true,
        			items: {
           				baseCls: 'x-plain',
            			html:'<div style="width:100%;height:320px;font-size:14px;overflow:auto;">' + errorStack.replace(/\n/g,'<br/>').replace(/(org.sninwo.[^\s]*)/g, '<font color="blue">$1</font>') + '</div>'
            		},
            		listeners:{
            			collapse: function(){
							errorWin.setWidth(400);
							errorWin.setHeight(170);
							errorWin.center();
						},
            			expand: function(){
							errorWin.setWidth(self.getWinWidth(800));
							errorWin.setHeight(self.getWinHeight(500));
							errorWin.center();
            			}
            		}
            	}]
            })],
            buttons: [{
                text: '关闭',
                handler: function(){
                	errorWin.close();
                	callback && callback.call();
                }
            }]
        });
    	errorWin.show();
	},
	viewObj: function(obj){
		var type = typeof obj;
		if (!obj || type === 'number' || type === 'string'){
			alert(obj);
			return;
		}
		var s = "";
		for (var p in obj){
			s += p + "=";
			if (typeof(obj[p]) == "function")
				s += "[function]";
			else
				s += obj[p];
			s += "\n";
		}
		var Ext = top.Ext;
		var win = new Ext.Window({
            title: '查看Javascript对象信息',
            width: 600,
            height: 400,
            layout: 'fit',
            plain:true,
            modal: true,
            bodyStyle:'padding:5px;',
            buttonAlign:'center',
            items: new Ext.form.TextArea({
            	value: s
            }),
            buttons: [{
                text: '关闭',
                handler: function(){win.close();}
            }]
		}).show();
	},
	//占位属性
	none: null
};

/**
 * 用来控制ajax返回结果的错误处理
 */
var _error_ = false;
Ext.Ajax.on('requestcomplete', function(conn, response, options){
	top.Ext.MessageBox.hide();
	MyUtils.stopWaiting();
	if (MyUtils.responseError(response, '错误提示')){
		_error_ = true;
	};
});

Ext.Ajax.on('requestexception', function(conn, response, options){
	top.Ext.MessageBox.hide();
	MyUtils.stopWaiting();
	if (MyUtils.responseError(response, '错误提示')){
		_error_ = true;
	};
});

/**
 * 调用时用来查看对象
 */
function debug(obj){
	MyUtils.viewObj(obj);
}